<script setup>
import {MENU_TYPE, MENU_TYPE_META, OPERATE_DRAWER_MODE, VISIBLE, VISIBLE_META} from "@/common/constant.js";
import {computed, ref} from "vue";
import {add, detailById, modifyById} from "@/apis/sys/menu.js";
import {obj2Array} from "@/utils/index.js";
import IconSelect from "@/components/icon-select.vue";
import {useMessage} from 'naive-ui'
import MenuTreeSelect from "../../../components/menu-tree-select.vue";

const message = useMessage()
const show = defineModel('show')
const props = defineProps({
  mode: {
    type: Number,
    default: OPERATE_DRAWER_MODE.DETAIL
  },
  id: {
    type: String,
    default: undefined
  }
})

const showSubmitBtn = computed(() => {
  return props.mode === OPERATE_DRAWER_MODE.ADD || props.mode === OPERATE_DRAWER_MODE.EDIT
})
const emits = defineEmits(['success'])
const formRef = ref(undefined)
const initFormDataValue = {
  component: undefined,
  icon: undefined,
  name: undefined,
  parentId: undefined,
  permission: undefined,
  sort: 1,
  type: MENU_TYPE.CATALOG,
  visible: VISIBLE.VISIBLE
}
const formData = ref({...initFormDataValue})

const onAfterEnter = () => {
  if (props.mode === OPERATE_DRAWER_MODE.DETAIL || props.mode === OPERATE_DRAWER_MODE.EDIT) {
    loadDetail(props.id)
  }
}

const onAfterLeave = () => {
  resetForm()
}
const resetForm = () => {
  formData.value = {...initFormDataValue}
};

const loadDetail = async (id) => {
  const {code, data} = await detailById(id)
  if (code === 0) {
    formData.value = data
    formData.value.checkedMenuIds = formData.value.menuIds
  }
}

const onFinish = () => {
  formRef.value.validate()
      .then(async () => {
        if (props.mode === OPERATE_DRAWER_MODE.ADD) {
          const {code} = await add(formData.value)
          if (code === 0) {
            message.success('新增成功')
            show.value = false
            emits('success')
          }
        } else if (props.mode === OPERATE_DRAWER_MODE.EDIT) {
          const {code} = await modifyById(props.id, formData.value)
          if (code === 0) {
            message.success('修改成功')
            show.value = false
            emits('success')
          }
        }
      })
}

const title = computed(() => {
  if (props.mode === OPERATE_DRAWER_MODE.ADD) {
    return '新增菜单'
  } else if (props.mode === OPERATE_DRAWER_MODE.EDIT) {
    return '修改菜单'
  } else {
    return '菜单详情'
  }
})

const rules = {
  parentId: [
    {required: true, message: '请选择上级菜单', trigger: 'change'}
  ],
  name: [
    {required: true, message: '请输入菜单名称', trigger: 'blur'}
  ],
  permission: [
    {required: true, message: '请输入菜单权限', trigger: 'blur'}
  ],
  type: [
    {required: true, message: '请选择菜单类型', trigger: 'change'}
  ],
  icon: [
      {required: true, message: '请选择菜单ICON', trigger: 'change'}
  ],
  component: [
    {required: true, message: '请输入菜单组件', trigger: 'blur'}
  ],
  sort: [
    {required: true, message: '请填写排序序号'}
  ],
  visible: [
    {required: true, message: '请设置是否可见', trigger: 'change'}
  ]
}

const disabled = computed(() => {
  return props.mode === OPERATE_DRAWER_MODE.DETAIL
})

const onMenuTypeChanged = (menuType) => {
  formData.value.type = menuType
  if (menuType === MENU_TYPE.CATALOG) {
    formData.value.component = undefined
  }
  if (menuType === MENU_TYPE.BUTTON) {
    formData.value.icon = undefined
    formData.value.component = undefined
  }
}

</script>

<template>
  <n-drawer
      v-model:show="show"
      resizable
      :min-width="502"
      :default-width="502"
      @after-enter="onAfterEnter"
      @after-leave="onAfterLeave">
    <n-drawer-content
        :title="title"
        closable
        :native-scrollbar="false">
      <n-space vertical size="large">
        <n-tabs type="line" :value="formData.type" @update-value="onMenuTypeChanged">
          <n-tab v-for="menuType in obj2Array(MENU_TYPE)" :key="menuType.key" :name="menuType.key"  :disabled="disabled">
            {{ MENU_TYPE_META[menuType.key] }}
          </n-tab>
        </n-tabs>
        <n-form :model="formData"
                label-placement="left"
                label-width="80"
                ref="formRef"
                :rules="rules">
          <n-form-item label="上级菜单" path="parentId">
            <menu-tree-select v-model:value="formData.parentId" :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="菜单名称" path="name">
            <n-input v-model:value="formData.name"
                     placeholder="请输入"
                     clearable
                     :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="菜单图标"
                       path="icon"
                       v-if="formData.type !== MENU_TYPE.BUTTON">
            <icon-select v-model:value="formData.icon"  :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="权限标识" path="permission">
            <n-input v-model:value="formData.permission"
                     placeholder="请输入"
                     clearable
                     :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="菜单组件" path="component" v-if="formData.type === MENU_TYPE.MENU">
            <n-input v-model:value="formData.component"
                     placeholder="请输入"
                     clearable
                     :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="排序序号" path="sort" v-if="formData.type !== MENU_TYPE.BUTTON">
            <n-input-number v-model:value="formData.sort" :min="1" :max="99" :disabled="disabled"/>
          </n-form-item>
          <n-form-item label="是否可见" path="visible">
            <n-radio-group v-model:value="formData.visible" :default-value="VISIBLE.VISIBLE" :disabled="disabled">
              <n-space>
                <n-radio v-for="visible in obj2Array(VISIBLE)" :value="visible.key">
                  {{ VISIBLE_META[visible.key] }}
                </n-radio>
              </n-space>
            </n-radio-group>
          </n-form-item>
        </n-form>
      </n-space>
      <template #footer>
        <n-space>
          <n-button type="primary" @click="onFinish" v-if="showSubmitBtn">提交</n-button>
          <n-button @click="show = false">取消</n-button>
        </n-space>
      </template>
    </n-drawer-content>
  </n-drawer>
</template>

<style scoped>

</style>